home *** CD-ROM | disk | FTP | other *** search
/ Dr. Windows 3 / dr win3.zip / dr win3 / COMMUNIC / UNIQWK21.ZIP / TALK.TXT < prev    next >
Text File  |  1993-07-11  |  14KB  |  425 lines

  1.                         Talkline - How it works.
  2.                         ~~~~~~~~~~~~~~~~~~~~~~~~
  3.  
  4.      Talkline is a sound of short duration, appended to the end of a message.
  5.      In this fist version, up to 5 seconds of sound can be added.
  6.      The purpose of this text file is to explain how the sound is coded
  7. and appended to the message.   This first version is called version "A" and
  8. has the following characterization:
  9.  
  10. 1-Sampling. - The sound bandwidth supports human voice only and so is sampled
  11.    at 5012.5Hz Hz, 8bits, with zero level at value 80h.
  12.  
  13. 2-Compression -
  14.    A - The signal is converted to 4 bits, first subtracting DC value (80h) and
  15.        using a log (base 2) conversion of the absolute value:
  16.             in           out
  17.                 0  ->  0
  18.           0.   .1  ->  1
  19.           2.   .3  ->  2
  20.           4.   .7  ->  3
  21.           8.  .15  ->  4
  22.          16.  .31  ->  5
  23.          32.  .63  ->  6
  24.          64. .127  ->  7
  25.        Now the signal is 4 bits with zero level at 0 (-16 to 15).
  26.  
  27.    B - The samples are packed 2 samples per byte, high nibble corresponding
  28.        to first sample and the low nibble to next one
  29.  
  30.         EX:
  31.         t = 0  0000hhhh  <-- 4 bit sample
  32.             1  0000LLLL
  33.  
  34.                 pack  ->  hhhhLLLL
  35.  
  36.    C - Run lenght encoded, using FFh as flag character.
  37.  
  38.        EX:
  39.        00 32 84 84 84 84 84 84 34 35 FF 54 54 FE FE FE FE FE FE
  40.  
  41.        is converted to:
  42.        00 32 FF 05 84 34 35 FF 01 FF 54 54 FF 06 FE
  43.  
  44. 3-Coding - The signal is coded using 7 bits, from 30h to AFh.
  45.  
  46.         EX:
  47.         0 - AAAAaaaa      - >   0 - 0AAAAaaa   +  30h
  48.         1 - BBBBbbbb            1 - 0BBBBbbb   +  30h
  49.         2 - CCCCcccc            2 - 0CCCCccc   +  30h
  50.         3 - DDDDdddd            3 - 0DDDDddd   +  30h
  51.         4 - EEEEeeee            4 - 0EEEEeee   +  30h
  52.         5 - FFFFffff            5 - 0FFFFfff   +  30h
  53.         6 - GGGGgggg            6 - 0GGGGggg   +  30h
  54.                                 7 - 0abcdefg   +  30h
  55.  
  56. 4-Saving - The result is appended to the end of message at 64 bytes per line,
  57.   with a header:
  58.  
  59.    "[TALK]"  - 6 bytes - Identify a talkline
  60.    1Bh,"[8m" - 4 bytes - ANSI command to disable output, to avoid trash on
  61.                mail readers/terminal emulators without sound capabilities.
  62.    "A"       - 1 byte  -  This version.   Letters A to H are reserved.
  63.    "00000"   - 5 bytes -  The size of the sound in bytes, after coding and
  64.                           without line feeds (E3h).
  65.    E3h       - 1 byte  -  The character used as LF by the QWK file format.
  66.  
  67.    .. follow first 64 bytes,E3h,  and so on...
  68.  
  69. =========================================================================
  70.  
  71.    As example, the routines, used  to compress and expand the voice signal.
  72.  
  73. //-----------------------------------------------------------------------
  74. UINT WaveCompress (LPSTR Pk, LPSTR Wav, UINT nS)
  75. //
  76. //      Wav - intput signal
  77. //      Pk  - output signal
  78. //      nS  - number of data points
  79. //
  80. {
  81.   register UINT k, T;
  82.   char M;
  83.   UINT Ncomp, nS;
  84.  
  85.   Log2(Wav, nS);                        ;4 bit convert
  86.   Ncomp = nS >> 1;
  87. //                                      pack data
  88.   _asm  {
  89.             LES   SI,Wav        ;ES:SI -> Wav
  90.             MOV   DI,SI
  91.             MOV   CX,Ncomp
  92.             JCXZ  DONE
  93.      L1:    MOV   AX,ES:[SI]
  94.             SHL   AL,4          ;shift to HI nibble
  95.             AND   AX,0FF0h      ;mask
  96.             OR    AL,AH         ;merge
  97.             STOSB               ;save
  98.             ADD   SI,2
  99.             LOOP  L1
  100.      DONE:
  101.          }
  102. //
  103.   nS = 0;
  104.   Wav[Ncomp] = (char)(Wav[Ncomp-1]+1);  //make last different
  105.   for(k=0; k<Ncomp; k++)                //run lenght encode
  106.   {  T = 1;
  107.      M = Wav[k];
  108.      while (M == Wav[k+T])              //iqual next?
  109.      { if(T == 253) break;
  110.        else T = T + 1;                  //yes, bump T
  111.      }
  112.      if(T > 2 || M == '\xFF')
  113.      { Wav[nS++] = 0xFF;                //mark
  114.        Wav[nS++] =(char)T;              //total
  115.        k = k + T - 1;                   //next
  116.      }
  117.      Wav[nS++] = M;                     //save data
  118.   }
  119.   Ncomp = Pack(Pk, Wav, nS);            //7 bits convert
  120.   return Ncomp;
  121. }
  122. //-----------------------------------------------------------------
  123. LONG WaveExpand (LPSTR Wav, LPSTR Pk, UINT nS)
  124. //
  125. //      Pk  - input signal
  126. //      Wav - output signal
  127. //      nS  - number of data points
  128. //
  129. {
  130.   register UINT T, k;
  131.   UINT Cnt;
  132.   LONG nExp, Pt;
  133.  
  134. //
  135.    nSamp = Unpack(Pk, Pk, nSamp);             // 8 bits convert
  136.    nExp = 0;                                  // run lenght decode
  137.    for(Pt=0; (UINT)Pt < nSamp; Pt++)
  138.    {  if(Pk[Pt] == (char) 0xFF )
  139.       { Cnt = (BYTE) Pk[++Pt];
  140.         T = (char)Pk[++Pt];
  141.         for(k = 0; k < Cnt; k++) Wav[nExp++] = (char)T;
  142.       }
  143.       else
  144.       { Wav[nExp++] = Pk[Pt]; }
  145.    }
  146.    Cnt =(UINT)nExp;                           //unpack
  147.    _asm {
  148.             LES   DI, Wav
  149.             MOV   BX,Cnt
  150.             OR    BX,BX
  151.             JZ    DONE
  152.             MOV   SI,DI
  153.             ADD   SI,BX         ;end of data
  154.             ADD   BX,BX         ;end of unpacked data
  155.      L1:    MOV   AL,ES:[SI]
  156.             MOV   AH,AL         ;copy
  157.             SHR   AL,4          ;do inverse operation
  158.             AND   AX,0F0Fh     ;mask
  159.             MOV   ES:[DI+BX],AX ;save
  160.             DEC   SI
  161.             SUB   BX,2
  162.             JAE   L1            ;for all data points
  163.      DONE:
  164.         }
  165. //
  166.    nExp = nExp + nExp;
  167.    Exp2(Wave, nExp);                            ;8 bit convert
  168.    return nExp;
  169. }
  170. //=======================================================================
  171.  
  172.         Assebly routines to convert to and from 7 bits.
  173.  
  174. ;-------------------------------------------------------------------------
  175. ;       UINT = Pack (LPSTR, LPSTR, UINT);
  176. ;
  177. _Pack   PROC    FAR
  178.         PUSH    BP
  179.         MOV     BP,SP
  180.         PUSHF
  181.         CLD                     ;up
  182.         PUSH    DS
  183.         PUSH    SI
  184.         PUSH    DI
  185.         XOR     AX,AX           ;zero return value
  186.         MOV     CX,[BP+14]      ;size  (up to 64k)
  187.         JCXZ    PACK9
  188.         LES     DI,[BP+6];
  189.         LDS     SI,[BP+10];     ;DS:SI -> string
  190.         XOR     BX,BX           ;byte count
  191.         ADD     CX,SI           ;offset end of input string
  192.         PUSH    DI              ;save it
  193. ;
  194. PACK1:  MOV     DX,BX           ;insert a 0E3h each 64 bytes
  195.         AND     DX,3FH          ;test
  196.         JNZ     @F
  197.         MOV     AL,0E3h         ;LF (on QWK...)
  198.         STOSB                   ;insert
  199. @@:     CMP     SI,CX           ;end of processing?
  200.         JAE     PACK2           
  201.         LODSW                   ;-- 1 & 2
  202.         SHR     AL,1            ;-> 7, bit 0 to CY
  203.         RCL     DH,1            ;CY to bit 0 on DH
  204.         SHR     AH,1            ;repeat to next byte
  205.         RCL     DH,1
  206.         ADD     AX,3030h        ;translate to 30-A0h
  207.         STOSW                   ;ok, save it
  208.         LODSW
  209.         SHR     AL,1            ;repeat for bytes 3 & 4
  210.         RCL     DH,1
  211.         SHR     AH,1
  212.         RCL     DH,1
  213.         ADD     AX,3030h
  214.         STOSW
  215.         LODSW
  216.         SHR     AL,1            ;and 5 & 6
  217.         RCL     DH,1
  218.         SHR     AH,1
  219.         RCL     DH,1
  220.         ADD     AX,3030h
  221.         STOSW
  222.         LODSB
  223.         SHR     AL,1            ;the last one...
  224.         RCL     DH,1            ;
  225.         MOV     AH,DH           ;save DH (7 saved bits)
  226.         ADD     AX,3030h        ;
  227.         STOSW                   ;
  228.         ADD     BX,8            ;total
  229.         JMP     PACK1
  230. PACK2:  MOV     AX,DI           ;new position
  231.         POP     DI              ;initial position
  232.         SUB     AX,DI           ;return total processed bytes
  233. PACK9:  XOR     DX,DX           ;AX:DX
  234.         POP     DI
  235.         POP     SI
  236.         POP     DS
  237.         POPF
  238.         MOV     SP,BP
  239.         POP     BP
  240.         RET
  241. _Pack   ENDP
  242. ;-------------------------------------------------------------
  243. ;       UINT = Unpack (LPSTR, LPSTR, UINT);
  244. ;
  245. _Unpack PROC    FAR
  246.